package com.meida.module.admin.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.meida.common.constants.CommonConstants;
import com.meida.common.exception.OpenAlertException;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.model.DeleteModel;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.model.SaveModel;
import com.meida.common.mybatis.model.UpdateModel;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.FlymeUtils;
import com.meida.common.utils.StringUtils;
import com.meida.module.admin.client.constants.BaseConstants;
import com.meida.module.admin.client.entity.BaseRole;
import com.meida.module.admin.client.entity.BaseRoleUser;
import com.meida.module.admin.client.entity.BaseUser;
import com.meida.module.admin.provider.mapper.BaseRoleMapper;
import com.meida.module.admin.provider.mapper.BaseRoleUserMapper;
import com.meida.module.admin.provider.service.BaseRoleService;
import com.meida.module.admin.provider.service.BaseUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Optional;


/**
 * @author zyf
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BaseRoleServiceImpl extends BaseServiceImpl<BaseRoleMapper, BaseRole> implements BaseRoleService {
    @Autowired
    private BaseRoleMapper baseRoleMapper;
    @Autowired
    private BaseRoleUserMapper baseRoleUserMapper;
    @Autowired
    private BaseUserService baseUserService;

    /**
     * 分页查询
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody pageList(Map map) {
        CriteriaQuery<BaseUser> cq = new CriteriaQuery(map, BaseRole.class);
        BaseRole query = cq.getEntity(BaseRole.class);
        cq.likeRight(FlymeUtils.isNotEmpty(query.getRoleCode()), "roleCode", query.getRoleCode())
                .likeRight(FlymeUtils.isNotEmpty(query.getRoleName()), "roleName", query.getRoleName());
        cq.orderByDesc("createTime");
        return basePageList(cq);
    }

    /**
     * 查询列表
     *
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<BaseRole> findAllList() {
        List<BaseRole> list = baseRoleMapper.selectList(new QueryWrapper<>());
        return list;
    }

    /**
     * 获取角色信息
     *
     * @param roleId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public BaseRole getRole(Long roleId) {
        return baseRoleMapper.selectById(roleId);
    }



    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BaseRole role, EntityMap extra) {
        ApiAssert.isFalse(String.format("%s编码已存在!", role.getRoleCode()), isExist(role.getRoleCode()));
        role.setStatus(Optional.ofNullable(role.getStatus()).orElse(BaseConstants.ENABLED));
        role.setIsPersist(Optional.ofNullable(role.getStatus()).orElse(BaseConstants.DISABLED));
        return ResultBody.ok();
    }

    /**
     * 更新角色
     *
     * @param role 角色
     * @return
     */
    @Override
    public BaseRole updateRole(BaseRole role) {
        BaseRole updated = getRole(role.getRoleId());
        ApiAssert.isEmpty("角色不存在!", updated);
        if (!updated.getRoleCode().equals(role.getRoleCode())) {
            // 和原来不一致重新检查唯一性
            if (isExist(role.getRoleCode())) {
                throw new OpenAlertException(String.format("%s编码已存在!", role.getRoleCode()));
            }
        }
        baseRoleMapper.updateById(role);
        return role;
    }

    /**
     * 更新系统角色
     *
     * @param model
     * @return
     */
    @Override
    public ResultBody edit(UpdateModel model) {
        CriteriaUpdate<BaseRole> cu = new CriteriaUpdate(model, BaseRole.class);
        BaseRole role = cu.getEntity(BaseRole.class);
        BaseRole updated = getRole(role.getRoleId());
        ApiAssert.isNotEmpty("角色不存在!", updated);
        if (!updated.getRoleCode().equals(role.getRoleCode())) {
            ApiAssert.isEmpty(String.format("%s编码已存在!", role.getRoleCode()), role.getRoleCode());
        }
        return baseEdit(cu,role);
    }

    /**
     * 删除角色
     *
     * @param deleteModel 角色
     * @return
     */
    @Override
    public void removeRole(DeleteModel deleteModel) {
        CriteriaDelete cd = new CriteriaDelete(deleteModel, BaseRole.class);
        Long[] ids = deleteModel.getIds();
        ApiAssert.isNotEmpty("参数不正确", ids);
        Long id = ids[0];
        BaseRole role = getRole(id);
        ApiAssert.isFalse("保留数据,不允许删除", role != null && role.getIsPersist().equals(BaseConstants.ENABLED));
        int count = getCountByRole(id);
        ApiAssert.isFalse("该角色下存在授权人员,不允许删除!", count > 0);
        baseDelete(cd);
    }

    /**
     * 检测角色编码是否存在
     *
     * @param roleCode
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Boolean isExist(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            throw new OpenAlertException("roleCode不能为空!");
        }
        QueryWrapper<BaseRole> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRole::getRoleCode, roleCode);
        return baseRoleMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 用户添加角色
     *
     * @param userId
     * @param roles
     * @return
     */
    @Override
    public void saveUserRoles(Long userId, String... roles) {
        if (userId == null || roles == null) {
            return;
        }
        BaseUser user = baseUserService.getUserById(userId);
        if (user == null) {
            return;
        }
        if (CommonConstants.ROOT.equals(user.getUserName())) {
            throw new OpenAlertException("默认用户无需分配!");
        }
        // 先清空,在添加
        removeUserRoles(userId);
        if (roles.length > 0) {
            for (String roleId : roles) {
                BaseRoleUser roleUser = new BaseRoleUser();
                roleUser.setUserId(userId);
                roleUser.setRoleId(Long.parseLong(roleId));
                baseRoleUserMapper.insert(roleUser);
            }
            // 批量保存
        }
    }

    /**
     * 角色添加成员
     *
     * @param roleId
     * @param userIds
     */
    @Override
    public void saveRoleUsers(Long roleId, String... userIds) {
        if (roleId == null || userIds == null) {
            return;
        }
        // 先清空,在添加
        removeRoleUsers(roleId);
        if (userIds.length > 0) {
            for (String userId : userIds) {
                BaseRoleUser roleUser = new BaseRoleUser();
                roleUser.setUserId(Long.parseLong(userId));
                roleUser.setRoleId(roleId);
                baseRoleUserMapper.insert(roleUser);
            }
            // 批量保存
        }
    }

    /**
     * 查询角色成员
     *
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<BaseRoleUser> findRoleUsers(Long roleId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getRoleId, roleId);
        return baseRoleUserMapper.selectList(queryWrapper);
    }

    /**
     * 获取角色所有授权组员数量
     *
     * @param roleId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public int getCountByRole(Long roleId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getRoleId, roleId);
        int result = baseRoleUserMapper.selectCount(queryWrapper);
        return result;
    }

    /**
     * 获取组员角色数量
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public int getCountByUser(Long userId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getUserId, userId);
        int result = baseRoleUserMapper.selectCount(queryWrapper);
        return result;
    }

    /**
     * 移除角色所有组员
     *
     * @param roleId
     * @return
     */
    @Override
    public void removeRoleUsers(Long roleId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getRoleId, roleId);
        baseRoleUserMapper.delete(queryWrapper);
    }

    /**
     * 移除组员的所有角色
     *
     * @param userId
     * @return
     */
    @Override
    public void removeUserRoles(Long userId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getUserId, userId);
        baseRoleUserMapper.delete(queryWrapper);
    }

    /**
     * 检测是否存在
     *
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Boolean isExist(Long userId, Long roleId) {
        QueryWrapper<BaseRoleUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseRoleUser::getRoleId, roleId);
        queryWrapper.lambda().eq(BaseRoleUser::getUserId, userId);
        baseRoleUserMapper.delete(queryWrapper);
        int result = baseRoleUserMapper.selectCount(queryWrapper);
        return result > 0;
    }


    /**
     * 获取组员角色
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<BaseRole> getUserRoles(Long userId) {
        List<BaseRole> roles = baseRoleUserMapper.selectRoleUserList(userId);
        return roles;
    }

    /**
     * 获取用户角色ID列表
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<Long> getUserRoleIds(Long userId) {
        return baseRoleUserMapper.selectRoleUserIdList(userId);
    }


}
